package engine

import (
	"dbManager/manager/config"
	"dbManager/manager/strategy/ParseConfigFileStrategy"
	"dbManager/manager/strategy/deleteStrategy"
	_ "github.com/mattn/go-sqlite3"
	"github.com/zhuxiujia/GoMybatis"
	"io/ioutil"
	"log"
	"reflect"
)

// DbManager 管理公共的变量
type DbManager struct {
	Engine                  GoMybatis.GoMybatisEngine
	SqlConfig               config.Config
	DeleteStrategy          deleteStrategy.DeleteStrategy
	ParseConfigFileStrategy ParseConfigFileStrategy.ParseConfigFileStrategy
}

func NewDbManager() Manager {
	var dbManager DbManager
	dbManager.Engine = GoMybatis.GoMybatisEngine{}.New()
	dbManager.Engine.TemplateDecoder().SetPrintElement(true)
	dbManager.Engine.SetPrintWarning(true)
	return &dbManager
}

//OpenSql 连接数据库
func (dbm *DbManager) OpenSql() {
	_, err := dbm.Engine.Open(dbm.SqlConfig.GetDriver(), dbm.SqlConfig.GetUrl())
	if err != nil {
		log.Println(err, "数据库连接失败,如未导入对应包，请先导入")
		return
	}
}

//LoadXmlMapper 加载xmlMapper文件
func (dbm *DbManager) LoadXmlMapper(mapper interface{}) {
	vit := reflect.ValueOf(mapper)
	if vit.Kind() != reflect.Ptr {
		log.Println("加载的" + vit.String() + "比须为指针")
	}

	for {
		if vit.Kind() == reflect.Ptr {
			vit = vit.Elem()
		} else {
			break
		}
	}
	MapperfileName := dbm.SqlConfig.GetMapperXmlPrefix() + vit.Type().Name() + config.FILEXMLSUFFIX
	file, err := ioutil.ReadFile(MapperfileName)
	log.Println(MapperfileName)
	if err != nil {
		log.Fatal(err, "找不到映射文件")
	}
	dbm.Engine.WriteMapperPtr(mapper, file)
}

// CreateXmlMapper 创建XML
func (dbm *DbManager) CreateXmlMapper(bean interface{}) {
	GoMybatis.OutPutXml(dbm.SqlConfig.GetMapperXmlPrefix()+reflect.TypeOf(bean).Name()+config.MAPPERXMLSUFFIX, GoMybatis.CreateXml("biz_"+GoMybatis.StructToSnakeString(bean), bean))
}

//SetDeleteStrategy 设置删除策略
func (dbm *DbManager) SetDeleteStrategy(deleteStrategy deleteStrategy.DeleteStrategy) {
	dbm.DeleteStrategy = deleteStrategy
}

//GetEngine 获取字段Engine
func (dbm *DbManager) GetEngine() GoMybatis.GoMybatisEngine {
	return dbm.Engine
}

//GetSqlConfig 获取字段SqlConfig
func (dbm *DbManager) GetSqlConfig() config.Config {
	return dbm.SqlConfig
}

//SetParseConfigFileStrategy 设置读取配置文件的策略
func (dbm *DbManager) SetParseConfigFileStrategy(parseConfigFileStrategy ...ParseConfigFileStrategy.ParseConfigFileStrategy) {
	if len(parseConfigFileStrategy) > 1 || len(parseConfigFileStrategy) == 0 {
		log.Println("传入的解析策略参数过多或者没有参数，将使用默认策略")
		dbm.ParseConfigFileStrategy = ParseConfigFileStrategy.DefaultReadConfigFileStrategy{}
		return
	}
	dbm.ParseConfigFileStrategy = parseConfigFileStrategy[0]
}

// GetParseConfigFileStrategy() 获取解析配置文件策略
func (dbm *DbManager) GetParseConfigFileStrategy() ParseConfigFileStrategy.ParseConfigFileStrategy {
	return dbm.ParseConfigFileStrategy
}

// SetConfig 设置配置文件解析结果
func (dbm *DbManager) SetConfig(config config.Config) {
	dbm.SqlConfig = config
}
